package com.meida.base.provider.listener;

import com.meida.common.base.entity.EntityMap;
import com.meida.common.constants.CommonConstants;
import com.meida.common.security.http.OpenRestTemplate;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.utils.JsonUtils;
import com.meida.common.utils.RedisUtils;
import com.meida.module.admin.client.entity.BaseAction;
import com.meida.module.admin.client.entity.BaseApi;
import com.meida.module.admin.client.entity.BaseMenu;
import com.meida.module.admin.provider.service.BaseActionService;
import com.meida.module.admin.provider.service.BaseApiService;
import com.meida.module.admin.provider.service.BaseAuthorityService;
import com.meida.module.admin.provider.service.BaseMenuService;
import com.meida.starter.rabbitmq.config.RabbitComponent;
import com.meida.starter.rabbitmq.core.BaseRabbiMqHandler;
import com.meida.starter.rabbitmq.listener.MqListener;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.Header;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * mq消息接收者
 *
 * @author zyf
 */
@Configuration
@Slf4j
@RabbitComponent(value = "resourceScanHandler")
public class ResourceScanHandler extends BaseRabbiMqHandler<EntityMap> {
    @Autowired
    private BaseApiService baseApiService;
    @Autowired
    private BaseAuthorityService baseAuthorityService;
    @Autowired
    private OpenRestTemplate restTemplate;


    @Autowired
    private BaseActionService baseActionService;

    @Autowired
    private BaseMenuService baseMenuService;

    @Autowired
    private RedisUtils redisUtils;


    /**
     * 接收API资源扫描消息
     */
    @RabbitListener(queues = "meida.scan.api.resource")
    public void ScanApiResourceQueue(EntityMap entityMap, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        super.onMessage(entityMap, deliveryTag, channel, new MqListener<EntityMap>() {
            @Override
            public void handler(EntityMap entityMap, Channel channel) {
                try {
                    log.info("###################################:");
                    String serviceId = entityMap.get("application");
                    List array = entityMap.get("mapping");
                    List codesArray = entityMap.get("codes");
                    Iterator iterator = array.iterator();
                    Map<Object, Object> notAuthList = new HashMap<>();
                    while (iterator.hasNext()) {
                        Map map = (Map) iterator.next();
                        try {
                            BaseApi api = JsonUtils.jsonToBean(JsonUtils.beanToJson(map), BaseApi.class);
                            BaseApi baseApi = baseApiService.getApi(api.getApiCode());

                            String actionName = api.getActionName();
                            String menuName = api.getMenuName();
                            if (FlymeUtils.isNotEmpty(menuName)) {
                                BaseMenu baseMenu = baseMenuService.getMenu(menuName);
                                String actionCode = api.getMethodName();
                                Boolean insert = false;
                                BaseAction baseAction = baseActionService.getAction(actionCode);
                                if (FlymeUtils.isEmpty(baseAction)) {
                                    baseAction = new BaseAction();
                                    baseAction.setIsPersist(CommonConstants.LEVEL_1);
                                    baseAction.setStatus(CommonConstants.ENABLED);
                                    insert = true;
                                }
                                baseAction.setActionCode(actionCode);
                                baseAction.setActionName(actionName);
                                if (FlymeUtils.isNotEmpty(baseMenu)) {
                                    baseAction.setMenuId(baseMenu.getMenuId());
                                }
                                baseAction.setServiceId(api.getServiceId());
                                if (insert) {
                                    baseActionService.addAction(baseAction);
                                } else {
                                    baseActionService.updateAction(baseAction);
                                }
                            }
                            if (baseApi == null) {
                                api.setIsOpen(1);
                                api.setIsPersist(1);
                                baseApiService.addApi(api);
                                if (api.getIsAuth().equals(0)) {
                                    notAuthList.put(api.getApiCode(), api.getPath());
                                }
                            } else {
                                api.setApiId(baseApi.getApiId());
                                api.setIsAuth(null);
                                if (baseApi.getIsAuth().equals(0)) {
                                    notAuthList.put(baseApi.getApiCode(), baseApi.getPath());
                                }
                                baseApiService.updateApi(api);
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                            log.error("添加资源error:", e.getMessage());
                        }

                    }
                    //免登录鉴权接口
                    if (FlymeUtils.isNotEmpty(notAuthList)) {
                        redisUtils.setProjectMap(CommonConstants.NOTAUTH_KEY + serviceId, notAuthList);
                    }
                    if (FlymeUtils.isNotEmpty(codesArray)) {
                        List<String> codes = codesArray;
                        // 清理无效权限数据
                        baseAuthorityService.clearInvalidApi(serviceId, codes);
                        restTemplate.refreshGateway();
                    }

                } catch (
                        Exception e) {
                    log.error("error:", e);
                }
            }
        });
    }
}
